package com.ustarlink.listviewdeletion;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    final ArrayList<View> mCheckedViews = new ArrayList<View>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final CheckBox usePositionCB = (CheckBox) findViewById(R.id.usePositionsCB);
        final Button deleteButton = (Button) findViewById(R.id.deleteButton);
        final ListView listView = (ListView) findViewById(R.id.listView);
        final ArrayList<String> cheesesList = new ArrayList<String>();
        for (int i = 0; i < Cheeses.sCheeseStrings.length; i++){
            cheesesList.add(Cheeses.sCheeseStrings[i]);
        }

        final StableArrayAdapter adapter = new StableArrayAdapter(this,
                android.R.layout.simple_list_item_multiple_choice, cheesesList);
        listView.setAdapter(adapter);
        listView.setItemsCanFocus(false);
        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        // Clicking the delete button fades out the currently selected views
        deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SparseBooleanArray checkedIterms = listView.getCheckedItemPositions();
                int numCheckedItems = checkedIterms.size();
                Log.i("ListView", checkedIterms.size() + "");
                for (int i = numCheckedItems - 1; i >= 0; --i) {
                    if (!checkedIterms.valueAt(i)) {
                        continue;
                    }
                    // Remove the actual data after the time period that we're going to run
                    // the fading animation
                    int position = checkedIterms.keyAt(i);
                    final String item = adapter.getItem(position);
                    if (!usePositionCB.isChecked()) {
                        v.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                adapter.remove(item);
                            }
                        }, 300);
                    } else {
                        // This is the correct way to do this: first wee whether the item is
                        // actually visible, and don't bother animating it if it's not.
                        // Next, get the view associated with the item at the time of deletion
                        // (not some old view chosen when item was clicked)
                        mCheckedViews.clear();
                        int positionScreen = position - listView.getFirstVisiblePosition();
                        if (positionScreen >= 0 &&
                                positionScreen < listView.getChildCount()) {
                            final View view = listView.getChildAt(positionScreen);
                            // All set to fade this view out. Using ViewPropertyAnimator accounts
                            // for possible recycling of views during the animation itself
                            // (See the ListViewAnimations example for more on this)
                            view.animate().alpha(0).withEndAction(new Runnable() {
                                @Override
                                public void run() {
                                    view.setAlpha(1);
                                    adapter.remove(item);
                                }
                            });
                        } else {
                            // Not animating the view, but don't delete it yet to avoid making the
                            // list shift due to offscreen deletions.
                            v.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    adapter.remove(item);
                                }
                            }, 300);
                        }
                    }

                }
                // THIS THE WRONG WAY TO DO THIS
                // We're basing our decision of the view to be animated based on outdated
                // information at selection time. Then we're going ahead and running an animation
                // on those views even when the selected items might not even be in view (in which
                // case we'll probably be mistakenly fading out something else that is on the
                // screen and is re-using that recycled view)
                for (int i = 0; i < mCheckedViews.size(); ++i) {
                    final View checkView = mCheckedViews.get(i);
                    checkView.animate().alpha(0).withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            checkView.setAlpha(1);
                        }
                    });
                }
                mCheckedViews.clear();
                adapter.notifyDataSetChanged();
            }
        });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                boolean checked = listView.isItemChecked(position);
                if (checked){
                    mCheckedViews.add(view);
                } else {
                    mCheckedViews.remove(view);
                }
            }
        });

    }

    /**
     * Created by cfm on 16-4-4.
     */
    private class StableArrayAdapter extends ArrayAdapter<String> {
        HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
        public StableArrayAdapter(Context context, int resource, List<String> objs) {
            super(context, resource, objs);
            for (int i = 0; i < objs.size(); i++){
                mIdMap.put(objs.get(i), i);
            }
        }

        @Override
        public long getItemId(int position) {
            String item = getItem(position);
            return mIdMap.get(item);
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }
    }
}
